1   /*
2    * Copyright (C) 2008 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect.testing;
18  
19  import com.google.common.collect.testing.features.CollectionFeature;
20  import com.google.common.collect.testing.features.Feature;
21  import com.google.common.collect.testing.testers.CollectionSerializationEqualTester;
22  import com.google.common.collect.testing.testers.ListAddAllAtIndexTester;
23  import com.google.common.collect.testing.testers.ListAddAllTester;
24  import com.google.common.collect.testing.testers.ListAddAtIndexTester;
25  import com.google.common.collect.testing.testers.ListAddTester;
26  import com.google.common.collect.testing.testers.ListCreationTester;
27  import com.google.common.collect.testing.testers.ListEqualsTester;
28  import com.google.common.collect.testing.testers.ListGetTester;
29  import com.google.common.collect.testing.testers.ListHashCodeTester;
30  import com.google.common.collect.testing.testers.ListIndexOfTester;
31  import com.google.common.collect.testing.testers.ListLastIndexOfTester;
32  import com.google.common.collect.testing.testers.ListListIteratorTester;
33  import com.google.common.collect.testing.testers.ListRemoveAllTester;
34  import com.google.common.collect.testing.testers.ListRemoveAtIndexTester;
35  import com.google.common.collect.testing.testers.ListRemoveTester;
36  import com.google.common.collect.testing.testers.ListRetainAllTester;
37  import com.google.common.collect.testing.testers.ListSetTester;
38  import com.google.common.collect.testing.testers.ListSubListTester;
39  import com.google.common.collect.testing.testers.ListToArrayTester;
40  import com.google.common.testing.SerializableTester;
41  
42  import junit.framework.TestSuite;
43  
44  import java.util.ArrayList;
45  import java.util.Collection;
46  import java.util.HashSet;
47  import java.util.List;
48  import java.util.Set;
49  
50  /**
51   * Creates, based on your criteria, a JUnit test suite that exhaustively tests
52   * a List implementation.
53   *
54   * @author George van den Driessche
55   */
56  public final class ListTestSuiteBuilder<E> extends
57      AbstractCollectionTestSuiteBuilder<ListTestSuiteBuilder<E>, E> {
58    public static <E> ListTestSuiteBuilder<E> using(
59        TestListGenerator<E> generator) {
60      return new ListTestSuiteBuilder<E>().usingGenerator(generator);
61    }
62  
63    @Override protected List<Class<? extends AbstractTester>> getTesters() {
64      List<Class<? extends AbstractTester>> testers
65          = Helpers.copyToList(super.getTesters());
66  
67      testers.add(CollectionSerializationEqualTester.class);
68      testers.add(ListAddAllAtIndexTester.class);
69      testers.add(ListAddAllTester.class);
70      testers.add(ListAddAtIndexTester.class);
71      testers.add(ListAddTester.class);
72      testers.add(ListCreationTester.class);
73      testers.add(ListEqualsTester.class);
74      testers.add(ListGetTester.class);
75      testers.add(ListHashCodeTester.class);
76      testers.add(ListIndexOfTester.class);
77      testers.add(ListLastIndexOfTester.class);
78      testers.add(ListListIteratorTester.class);
79      testers.add(ListRemoveAllTester.class);
80      testers.add(ListRemoveAtIndexTester.class);
81      testers.add(ListRemoveTester.class);
82      testers.add(ListRetainAllTester.class);
83      testers.add(ListSetTester.class);
84      testers.add(ListSubListTester.class);
85      testers.add(ListToArrayTester.class);
86      return testers;
87    }
88  
89    /**
90     * Specifies {@link CollectionFeature#KNOWN_ORDER} for all list tests, since
91     * lists have an iteration ordering corresponding to the insertion order.
92     */
93    @Override public TestSuite createTestSuite() {
94      withFeatures(CollectionFeature.KNOWN_ORDER);
95      return super.createTestSuite();
96    }
97  
98    @Override
99    protected
100       List<TestSuite>
101       createDerivedSuites(
102           FeatureSpecificTestSuiteBuilder<
103               ?, ? extends OneSizeTestContainerGenerator<Collection<E>, E>> parentBuilder) {
104     List<TestSuite> derivedSuites = new ArrayList<TestSuite>(
105         super.createDerivedSuites(parentBuilder));
106 
107     if (parentBuilder.getFeatures().contains(CollectionFeature.SERIALIZABLE)) {
108       derivedSuites.add(ListTestSuiteBuilder
109           .using(new ReserializedListGenerator<E>(parentBuilder.getSubjectGenerator()))
110           .named(getName() + " reserialized")
111           .withFeatures(computeReserializedCollectionFeatures(parentBuilder.getFeatures()))
112           .suppressing(parentBuilder.getSuppressedTests())
113           .createTestSuite());
114     }
115     return derivedSuites;
116   }
117 
118   static class ReserializedListGenerator<E> implements TestListGenerator<E>{
119     final OneSizeTestContainerGenerator<Collection<E>, E> gen;
120 
121     private ReserializedListGenerator(OneSizeTestContainerGenerator<Collection<E>, E> gen) {
122       this.gen = gen;
123     }
124 
125     @Override
126     public SampleElements<E> samples() {
127       return gen.samples();
128     }
129 
130     @Override
131     public List<E> create(Object... elements) {
132       return (List<E>) SerializableTester.reserialize(gen.create(elements));
133     }
134 
135     @Override
136     public E[] createArray(int length) {
137       return gen.createArray(length);
138     }
139 
140     @Override
141     public Iterable<E> order(List<E> insertionOrder) {
142       return gen.order(insertionOrder);
143     }
144   }
145 
146   private static Set<Feature<?>> computeReserializedCollectionFeatures(
147       Set<Feature<?>> features) {
148     Set<Feature<?>> derivedFeatures = new HashSet<Feature<?>>();
149     derivedFeatures.addAll(features);
150     derivedFeatures.remove(CollectionFeature.SERIALIZABLE);
151     derivedFeatures.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS);
152     return derivedFeatures;
153   }
154 }